package com.yuyou.fn.updater.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Optional;
import com.google.common.cache.LoadingCache;
import com.yuyou.fn.balance.entity.BalanceWithdrawal;
import com.yuyou.fn.common.database.event.EventHandler;
import com.yuyou.fn.common.database.event.IEventHandler;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.BigDecimals;
import com.yuyou.fn.common.util.CacheUtils;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.PayLecture;
import com.yuyou.fn.platform.service.IAreaTeamService;
import com.yuyou.fn.report.entity.Charge;
import com.yuyou.fn.report.service.IChargeService;
import com.yuyou.fn.settlement.entity.*;
import com.yuyou.fn.settlement.service.IAccountRechargeService;
import com.yuyou.fn.settlement.service.INewPayRecordService;
import com.yuyou.fn.settlement.vo.PayWay;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutionException;

@EventHandler(tables = {"yyfn.pay_record", "yyfn.student_refund","yyfn.balance_withdrawal" ,"yyfn.new_pay_record" })
@Component
public class ChargeUpdater implements IEventHandler {

    private final static Logger log = LoggerFactory.getLogger(ChargeUpdater.class);

    @Resource
    private ICourseOrderService courseOrderService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private IStudentService studentService;

    @Resource
    private ICampusService campusService;

    @Resource
    private ICourseTemplateService courseTemplateService;

    @Resource
    private IChargeService chargeService;

    @Resource
    private Redisson redisson ;

    @Resource
    private IAreaTeamService areaTeamService;

    @Resource
    private IAccountRechargeService accountRechargeService;

    private LoadingCache<Long, com.google.common.base.Optional<CourseTemplate>> loadingCacheOfCourseTemplate ;
    private LoadingCache<Long, com.google.common.base.Optional<CourseClass>> loadingCacheOfCourseClass ;
    private LoadingCache<Long, Optional<Student>> loadingCacheOfStudent ;

    @PostConstruct
    public void init(){
        this.loadingCacheOfCourseTemplate = CacheUtils.buildCache(courseTemplateService::findById);
        this.loadingCacheOfCourseClass = CacheUtils.buildCache(courseClassService::findById);
        this.loadingCacheOfStudent = CacheUtils.buildCache(studentService::findById);
    }


    @Override
    public void insert(String tableName, JSONArray rowList) {
        build(tableName, rowList);
    }

    @Override
    public void update(String tableName, JSONArray rowList, Set<String> updateColumns) {
        build(tableName, rowList);
    }

    @Override
    public void delete(String tableName, JSONArray rowList) {

    }

    private void build(String tableName, JSONArray rowList) {
        try{
            if (tableName.contains("new_pay_record")) {
                handleNewPayRecord(rowList);
            }else if (tableName.contains("pay_record")) {
                handlePayRecord(rowList);
            } else if (tableName.contains("student_refund")) {
                handleStudentRefund(rowList);
            }else if (tableName.contains("balance_withdrawal")) {
                handleBalanceWithdrawal(rowList);
            }
        }catch (Exception e){
            throw new RuntimeException(e) ;
        }
    }



    private void handleBalanceWithdrawal(JSONArray rowList) {

        for (int i = 0; i < rowList.size(); i++) {
            JSONObject row = rowList.getJSONObject(i);

            BalanceWithdrawal balanceWithdrawal = row.toJavaObject(BalanceWithdrawal.class);

            if (balanceWithdrawal.getStatus().intValue() == 1 && balanceWithdrawal.getPayStatus() == 1 ) {
                saveOrUpdateBalanceWithdrawal(balanceWithdrawal);
            }
        }
    }

    private void saveOrUpdateBalanceWithdrawal(BalanceWithdrawal balanceWithdrawal) {

        Student student = studentService.findById(balanceWithdrawal.getApplierMainAccountId());

        Charge charge = new Charge();
        charge.setChargeId(balanceWithdrawal.getBalanceWithdrawalId() + "|" + balanceWithdrawal.getStatus());
        charge.setOperator(balanceWithdrawal.getOperatorName());
        charge.setYear(DateUtils.toCalendar(balanceWithdrawal.getCreateTime()).get(Calendar.YEAR));
        charge.setBusType(5);
        charge.setOrderId(String.valueOf(balanceWithdrawal.getBalanceWithdrawalId()));
        charge.setOrderStatus(balanceWithdrawal.getStatus());
        charge.setAreaTeamId(balanceWithdrawal.getAreaTeamId());
        charge.setAreaTeamName(areaTeamService.findTeamNameById(balanceWithdrawal.getAreaTeamId()));


        if (balanceWithdrawal.getPayStatus()==1){
            charge.setDailyStatus(1);
        }


        charge.setStudentNo(student.getStudentNo());
        charge.setStudentGradeId(student.getGradeId());
        charge.setStudentGradeName(student.getGradeName());
        charge.setStudentId(student.getStudentId());
        charge.setStudentName(student.getName());
        charge.setStudentSchool(student.getSchool());
        charge.setIsNewStudent(student.getRegClassAmount() > 0 ? 1 : 0);

        charge.setPayWay(null);
        charge.setPaidAmount(BigDecimal.ZERO);
        charge.setDiscountAmount(BigDecimal.ZERO);
        charge.setDiscountReason("");


        charge.setRefundAmount(balanceWithdrawal.getAmount());
        charge.setCreateTime(balanceWithdrawal.getPayTime());
        charge.setUpdateTime(balanceWithdrawal.getPayTime());

        try {
            chargeService.insertSelective(charge);
        } catch (Exception e) {
            chargeService.updateSelectiveById(charge);
        }

    }


    private void handleStudentRefund(JSONArray rowList) {

        for (int i = 0; i < rowList.size(); i++) {
            JSONObject row = rowList.getJSONObject(i);


            StudentRefund studentRefund = row.toJavaObject(StudentRefund.class);

            if (studentRefund.getStatus().intValue() == 1 && studentRefund.getPayStatus() == 1) {
                saveOrUpdateStudentRefund(studentRefund);
            }

        }


    }

    private void saveOrUpdateStudentRefund(StudentRefund studentRefund) {
        StudentReg studentReg = studentRegService.findById(studentRefund.getStudentRegId());
        CourseOrder courseOrder = courseOrderService.findById(studentReg.getCourseOrderId());

        CourseClass courseClass = courseClassService.findById(studentReg.getClassId());

        if( ",73,74,75,76,77,78,79,80,".contains(String.valueOf(courseClass.getPeriodId())) || "562476894868471808".contains(String.valueOf(courseClass.getAreaTeamId()))){
            return ;
        }

        Student student = studentService.findById(studentReg.getStudentId());
        CourseTemplate courseTemplate = courseTemplateService.findById(courseClass.getCourseTemplateId());

        Charge charge = new Charge();
        charge.setChargeId(studentRefund.getStudentRefundId() + "|" + studentRefund.getStatus());
        charge.setOperator(studentRefund.getApplyOperator());
        charge.setYear(DateUtils.toCalendar(studentRefund.getCreateTime()).get(Calendar.YEAR));
        charge.setBusType(2);
        charge.setOrderId(String.valueOf(studentRefund.getStudentRefundId()));
        charge.setOrderStatus(studentRefund.getStatus());
        charge.setAreaTeamId(courseClass.getAreaTeamId());
        charge.setAreaTeamName(courseClass.getAreaTeamName());
        charge.setBusTeamId(courseClass.getBusTeamId());
        charge.setBusTeamName(courseClass.getBusTeamName());

        charge.setRegId(studentReg.getRegId());

        charge.setChargeCampusId(courseClass.getCampusId());
        charge.setChargeCampus(courseClass.getCampusName());

        charge.setRegCampusId(courseClass.getCampusId());
        charge.setRegCampus(courseClass.getCampusName());

        if (studentRefund.getPayStatus()==1){
            charge.setDailyStatus(1);
        }

        charge.setClassId(courseClass.getClassId());
        charge.setClassName(courseClass.getClassName());
        charge.setCourseId(courseClass.getCourseTemplateId());
        charge.setCourseName(courseTemplate.getCourseName());
        charge.setGradeId(courseClass.getGradeId());
        charge.setGradeName(courseClass.getGradeName());
        charge.setSubjectId(courseClass.getSubjectId());
        charge.setSubjectName(courseClass.getSubjectName());
        charge.setProductId(courseTemplate.getProductId());
        charge.setProductName(courseTemplate.getProductName());
        charge.setSeason(courseClass.getPeriodName());
        charge.setPeriodId(courseClass.getPeriodId());
        charge.setPeriodName(courseClass.getPeriodName());

        charge.setStudentNo(student.getStudentNo());
        charge.setStudentGradeId(student.getGradeId());
        charge.setStudentGradeName(student.getGradeName());
        charge.setStudentId(student.getStudentId());
        charge.setStudentName(student.getName());
        charge.setStudentSchool(student.getSchool());
        charge.setIsNewStudent(student.getRegClassAmount() > 0 ? 1 : 0);

        charge.setPayWay(null);
        charge.setPaidAmount(BigDecimal.ZERO);
        charge.setDiscountAmount(BigDecimal.ZERO);
        charge.setDiscountReason("");
        charge.setRegFrom(courseOrder.getRegFrom());



        charge.setRefundWay(studentRefund.getRefundWay());
        charge.setRefundAmount(studentRefund.getAmount());
        charge.setApplyRefundTime(studentRefund.getCreateTime());
        charge.setRemark("退费讲次:" + studentRefund.getRefundLecture());

        charge.setCreateTime(studentRefund.getPayTime());
        charge.setUpdateTime(studentRefund.getPayTime());

        try {
            chargeService.insertSelective(charge);
        } catch (Exception e) {
            chargeService.updateSelectiveById(charge);
        }
    }

    private void handlePayRecord(JSONArray rowList) {

        for (int i = 0; i < rowList.size(); i++) {
            JSONObject row = rowList.getJSONObject(i);

            //{"amount":"0.10","update_time":"2017-07-06 14:44:34","create_time":"2017-05-27 17:22:28","pay_record_id":"562553498508460032","pay_way":"4","campus_id":"0","operator":"","course_order_id":"562538953085812736"}

            PayRecord payRecord = row.toJavaObject(PayRecord.class);
            RLock lock = redisson.getLock(String.format("saveOrUpdatePayRecord:%d", payRecord.getBusOrderId()));
            lock.lock();
            try {
                saveOrUpdatePayRecord(payRecord);
            }finally {
                lock.unlock();
            }


        }


    }

    private void handleNewPayRecord(JSONArray rowList) throws ExecutionException {

        for (int i = 0; i < rowList.size(); i++) {
            JSONObject row = rowList.getJSONObject(i);

            NewPayRecord newPayRecord = row.toJavaObject(NewPayRecord.class);
            RLock lock = redisson.getLock(String.format("saveOrUpdatePayRecord:%d", newPayRecord.getBusOrderId()));
            lock.lock();
            try {
                saveOrUpdateNewPayRecord(newPayRecord);
            }finally {
                lock.unlock();
            }


        }


    }

    private void saveOrUpdatePayRecord(PayRecord payRecord) {
        Campus chargeCampus = null;
        if (payRecord.getCampusId() != null && payRecord.getCampusId() != 0) {
            chargeCampus = campusService.findById(payRecord.getCampusId());
        }

        String payChannelTransactionNo = resolvePayChannelTransactionNo(payRecord.getPayWay(),payRecord.getPayInfoExt()) ;


        if(payRecord.getBusType() == 0 ){
            CourseOrder courseOrder = courseOrderService.findById(payRecord.getBusOrderId());
            List<StudentReg> studentRegList = studentRegService.findStudentRegByCourseOrderId(courseOrder.getCourseOrderId());


            Collections.sort(studentRegList);


            BigDecimal amount2 = BigDecimal.ZERO;
            for (int i = 0 ; i < studentRegList.size()  ; i++ ) {
                StudentReg studentReg = studentRegList.get(i);
                CourseClass courseClass = courseClassService.findById(studentReg.getClassId());
                if( ",73,74,75,76,77,78,79,80,".contains(String.valueOf(courseClass.getPeriodId())) || "562476894868471808".contains(String.valueOf(courseClass.getAreaTeamId()))){
                    continue ;
                }
                Student student = studentService.findById(studentReg.getStudentId());
                CourseTemplate courseTemplate = courseTemplateService.findById(courseClass.getCourseTemplateId());
                String chargeId  = studentReg.getRegId() + "|"  + payRecord.getPayRecordId( ) ;
                if(payRecord.getHidden() == 1 ){
                    chargeService.deleteById(chargeId);
                    continue;
                }

                Charge charge = new Charge();
                charge.setChargeId(chargeId);
                charge.setPayChannelTransactionNo(payChannelTransactionNo);
                charge.setOperator(payRecord.getOperator());
                charge.setYear(DateUtils.toCalendar(courseOrder.getCreateTime()).get(Calendar.YEAR));
                charge.setBusType(0);
                charge.setOrderId( courseOrder.getRegFrom() == 1 ? courseOrder.getParentOrderId() + "|" +String.valueOf(courseOrder.getCourseOrderId()) : String.valueOf(courseOrder.getCourseOrderId()) );
                charge.setOrderStatus(courseOrder.getChargingStatus());
                charge.setAreaTeamId(courseClass.getAreaTeamId());
                charge.setAreaTeamName(courseClass.getAreaTeamName());
                charge.setBusTeamId(courseClass.getBusTeamId());
                charge.setBusTeamName(courseClass.getBusTeamName());

                charge.setRegId(studentReg.getRegId());

                if (chargeCampus != null) {
                    charge.setChargeCampus(chargeCampus.getCampusName());
                    charge.setChargeCampusId(chargeCampus.getCampusId());
                }else {
                    charge.setChargeCampusId(courseClass.getCampusId());
                    charge.setChargeCampus(courseClass.getCampusName());
                }
                if (courseOrder.getRegFrom() == 1){
                /*网报缴费校区同报名校区，自动日结*/
                    charge.setDailyStatus(1);
                }

                charge.setRegCampusId(courseClass.getCampusId());
                charge.setRegCampus(courseClass.getCampusName());

                charge.setClassId(courseClass.getClassId());
                charge.setClassName(courseClass.getClassName());
                charge.setCourseId(courseClass.getCourseTemplateId());
                charge.setCourseName(courseTemplate.getCourseName());
                charge.setGradeId(courseClass.getGradeId());
                charge.setGradeName(courseClass.getGradeName());
                charge.setSubjectId(courseClass.getSubjectId());
                charge.setSubjectName(courseClass.getSubjectName());
                charge.setProductId(courseTemplate.getProductId());
                charge.setProductName(courseTemplate.getProductName());
                charge.setSeason(courseClass.getPeriodName());
                charge.setPeriodId(courseClass.getPeriodId());
                charge.setPeriodName(courseClass.getPeriodName());

                charge.setStudentNo(student.getStudentNo());
                charge.setStudentGradeId(student.getGradeId());
                charge.setStudentGradeName(student.getGradeName());
                charge.setStudentId(student.getStudentId());
                charge.setStudentName(student.getName());
                charge.setStudentSchool(student.getSchool());
                charge.setIsNewStudent(student.getRegClassAmount() > 0 ? 1 : 0);

                if (payRecord.getPayWay() == 4) {//修正在线支付方式
                    charge.setPayWay(detectOnlinePayWay(payRecord.getPayInfoExt()));
                } else {
                    charge.setPayWay(payRecord.getPayWay());
                }
                if (payRecord.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                    charge.setPaidAmount(BigDecimal.ZERO);
                } else {
                    BigDecimal p  = BigDecimals.toFixed2( BigDecimals.calProportion(payRecord.getAmount(), studentReg.getTotalAmount(), courseOrder.getPayableAmount()),2);
                    if(i == studentRegList.size() - 1 ){
                        p = payRecord.getAmount().subtract( amount2 );
                    }else{
                        amount2 = amount2.add(p);
                    }
                    charge.setPaidAmount(p);
                }

                charge.setDiscountAmount(studentReg.getSrcTotalAmount().subtract(studentReg.getTotalAmount()));

                if (studentReg.getDiscountDetail() != null ) {
                    String[] spilts  = studentReg.getDiscountDetail().split(",");
                    List<String> discountNames = new ArrayList<>(spilts.length);
                    for(String s : spilts){
                        discountNames.add(s.split("\\|")[0]);
                    }
                    charge.setDiscountReason(StringUtils.join(discountNames,","));
                }

                charge.setRegFrom(courseOrder.getRegFrom());
                charge.setPayableAmount(studentReg.getTotalAmount());


                charge.setCreateTime(payRecord.getCreateTime());
                charge.setUpdateTime(payRecord.getUpdateTime());

                try {
                    chargeService.insertSelective(charge);
                } catch (Exception e) {
                    charge.setPaidAmount(null);
                    chargeService.updateSelectiveById(charge);
                }
            }
        }else if(payRecord.getBusType() == 1 ){

            AccountRecharge accountRecharge = accountRechargeService.findById(payRecord.getBusOrderId());

            Student student = studentService.findById(accountRecharge.getMainAccountId());

            Charge charge = new Charge();
            charge.setChargeId(String.valueOf(accountRecharge.getAccountRechargeId()));
            charge.setPayChannelTransactionNo(payChannelTransactionNo);
            charge.setOperator(accountRecharge.getOperatorName());
            charge.setYear(DateUtils.toCalendar(accountRecharge.getCreateTime()).get(Calendar.YEAR));
            charge.setBusType(6);
            charge.setOrderId(String.valueOf(accountRecharge.getAccountRechargeId()));
            charge.setOrderStatus(1);//成功
            charge.setAreaTeamId(accountRecharge.getAreaTeamId());
            charge.setAreaTeamName(areaTeamService.findTeamNameById(accountRecharge.getAreaTeamId()));
            charge.setChargeCampusId(accountRecharge.getCampusId());
            charge.setChargeCampus(accountRecharge.getCampusName());
            charge.setDailyStatus(1);
            charge.setStudentNo(student.getStudentNo());
            charge.setStudentGradeId(student.getGradeId());
            charge.setStudentGradeName(student.getGradeName());
            charge.setStudentId(student.getStudentId());
            charge.setStudentName(student.getName());
            charge.setStudentSchool(student.getSchool());
            charge.setIsNewStudent(student.getRegClassAmount() > 0 ? 1 : 0);

            if (payRecord.getPayWay() == 4) {//修正在线支付方式
                charge.setPayWay(detectOnlinePayWay(payRecord.getPayInfoExt()));
            } else {
                charge.setPayWay(payRecord.getPayWay());
            }

            charge.setPaidAmount(accountRecharge.getAmount());
            charge.setDiscountAmount(BigDecimal.ZERO);
            charge.setDiscountReason("");
            charge.setRemark(accountRecharge.getRemark());
            charge.setRefundAmount(BigDecimal.ZERO);
            charge.setCreateTime(accountRecharge.getCreateTime());
            charge.setUpdateTime(accountRecharge.getUpdateTime());

            try {
                chargeService.insertSelective(charge);
            } catch (Exception e) {
                chargeService.updateSelectiveById(charge);
            }
        }
    }

    private void saveOrUpdateNewPayRecord(NewPayRecord newPayRecord) throws ExecutionException {
        Campus chargeCampus = null;
        if (newPayRecord.getCampusId() != null && newPayRecord.getCampusId() != 0) {
            chargeCampus = campusService.findById(newPayRecord.getCampusId());
        }



        if(newPayRecord.getBusType() == 0 && StringUtils.isNotEmpty(newPayRecord.getExtra())){

            CourseOrder courseOrder = courseOrderService.findById(newPayRecord.getBusOrderId());
            List<StudentReg> studentRegList = studentRegService.findStudentRegByCourseOrderId(courseOrder.getCourseOrderId());

            Map<Long,StudentReg> regId2StudentReg = BeanUtils.toMap(studentRegList,"regId");

            for(PayWay payWay : JSON.parseArray(newPayRecord.getPayWays()).toJavaList(PayWay.class) ){
                BigDecimal t = BigDecimal.ZERO ;

                List<PayLecture> payLectures = JSON.parseArray(newPayRecord.getExtra()).toJavaList(PayLecture.class);
                for(int i = 0; i < payLectures.size() ; i++){
                    PayLecture payLecture = payLectures.get(i);
                    BigDecimal b = null ;
                    if(i < payLectures.size() - 1 ){
                        b = BigDecimals.toFixed2(BigDecimals.calProportion(payWay.getAmount(), payLecture.getPayAmount(), newPayRecord.getAmount()) ,2 );
                        t = t.add(b);
                    }else{
                        b = payWay.getAmount().subtract(t);
                    }
                    StudentReg studentReg = regId2StudentReg.get(payLecture.getRegId());
                    Student student = loadingCacheOfStudent.get(studentReg.getStudentId()).get();
                    CourseClass courseClass = loadingCacheOfCourseClass.get(studentReg.getClassId()).get();
                    CourseTemplate courseTemplate = loadingCacheOfCourseTemplate.get(courseClass.getCourseTemplateId()).get();

                    String chargeId  = studentReg.getRegId() + "|"  + newPayRecord.getPayRecordId( ) + "|" + payWay.getPayWay();

                    Charge charge = new Charge();
                    charge.setChargeId(chargeId);
                    charge.setPayChannelTransactionNo(resolvePayChannelTransactionNo(payWay.getPayWay(),payWay.getMorePayInfo() ));
                    charge.setOperator(newPayRecord.getOperator());
                    charge.setYear(DateUtils.toCalendar(courseOrder.getCreateTime()).get(Calendar.YEAR));
                    charge.setBusType(0);
                    charge.setOrderId( courseOrder.getRegFrom() == 1 ? courseOrder.getParentOrderId() + "|" +String.valueOf(courseOrder.getCourseOrderId()) : String.valueOf(courseOrder.getCourseOrderId()) );
                    charge.setOrderStatus(courseOrder.getChargingStatus());
                    charge.setAreaTeamId(courseClass.getAreaTeamId());
                    charge.setAreaTeamName(courseClass.getAreaTeamName());
                    charge.setBusTeamId(courseClass.getBusTeamId());
                    charge.setBusTeamName(courseClass.getBusTeamName());

                    charge.setRegId(studentReg.getRegId());

                    if (chargeCampus != null) {
                        charge.setChargeCampus(chargeCampus.getCampusName());
                        charge.setChargeCampusId(chargeCampus.getCampusId());
                    }else {
                        charge.setChargeCampusId(courseClass.getCampusId());
                        charge.setChargeCampus(courseClass.getCampusName());
                    }
                    if (courseOrder.getRegFrom() == 1){
                        /*网报缴费校区同报名校区，自动日结*/
                        charge.setDailyStatus(1);
                    }

                    charge.setRegCampusId(courseClass.getCampusId());
                    charge.setRegCampus(courseClass.getCampusName());

                    charge.setClassId(courseClass.getClassId());
                    charge.setClassName(courseClass.getClassName());
                    charge.setCourseId(courseClass.getCourseTemplateId());
                    charge.setCourseName(courseTemplate.getCourseName());
                    charge.setGradeId(courseClass.getGradeId());
                    charge.setGradeName(courseClass.getGradeName());
                    charge.setSubjectId(courseClass.getSubjectId());
                    charge.setSubjectName(courseClass.getSubjectName());
                    charge.setProductId(courseTemplate.getProductId());
                    charge.setProductName(courseTemplate.getProductName());
                    charge.setSeason(courseClass.getPeriodName());
                    charge.setPeriodId(courseClass.getPeriodId());
                    charge.setPeriodName(courseClass.getPeriodName());

                    charge.setStudentNo(student.getStudentNo());
                    charge.setStudentGradeId(student.getGradeId());
                    charge.setStudentGradeName(student.getGradeName());
                    charge.setStudentId(student.getStudentId());
                    charge.setStudentName(student.getName());
                    charge.setStudentSchool(student.getSchool());
                    charge.setIsNewStudent(student.getRegClassAmount() > 0 ? 1 : 0);

                    if (payWay.getPayWay() == 4) {//修正在线支付方式
                        charge.setPayWay(detectOnlinePayWay(payWay.getMorePayInfo()));
                    } else {
                        charge.setPayWay(payWay.getPayWay());
                    }
                    charge.setPaidAmount(b);
                    charge.setDiscountAmount(studentReg.getSrcTotalAmount().subtract(studentReg.getTotalAmount()));

                    if (studentReg.getDiscountDetail() != null ) {
                        String[] spilts  = studentReg.getDiscountDetail().split(",");
                        List<String> discountNames = new ArrayList<>(spilts.length);
                        for(String s : spilts){
                            discountNames.add(s.split("\\|")[0]);
                        }
                        charge.setDiscountReason(StringUtils.join(discountNames,","));
                    }
                    charge.setRegFrom(courseOrder.getRegFrom());
                    charge.setPayableAmount(studentReg.getTotalAmount());
                    charge.setCreateTime(newPayRecord.getCreateTime());
                    charge.setUpdateTime(newPayRecord.getUpdateTime());
                    try {
                        chargeService.insertSelective(charge);
                    } catch (Exception e) {
                        charge.setPaidAmount(null);
                        chargeService.updateSelectiveById(charge);
                    }
                }
            }

        }else if(newPayRecord.getBusType() == 1 ){

            AccountRecharge accountRecharge = accountRechargeService.findById(newPayRecord.getBusOrderId());

            Student student = loadingCacheOfStudent.get(accountRecharge.getMainAccountId()).get();

            for(PayWay payWay : JSON.parseArray(newPayRecord.getPayWays()).toJavaList(PayWay.class) ){
                Charge charge = new Charge();
                charge.setChargeId(String.valueOf(accountRecharge.getAccountRechargeId()));
                charge.setPayChannelTransactionNo(resolvePayChannelTransactionNo(payWay.getPayWay(),payWay.getMorePayInfo()));
                charge.setOperator(accountRecharge.getOperatorName());
                charge.setYear(DateUtils.toCalendar(accountRecharge.getCreateTime()).get(Calendar.YEAR));
                charge.setBusType(6);
                charge.setOrderId(String.valueOf(accountRecharge.getAccountRechargeId()));
                charge.setOrderStatus(1);//成功
                charge.setAreaTeamId(accountRecharge.getAreaTeamId());
                charge.setAreaTeamName(areaTeamService.findTeamNameById(accountRecharge.getAreaTeamId()));
                charge.setChargeCampusId(accountRecharge.getCampusId());
                charge.setChargeCampus(accountRecharge.getCampusName());
                charge.setDailyStatus(1);
                charge.setStudentNo(student.getStudentNo());
                charge.setStudentGradeId(student.getGradeId());
                charge.setStudentGradeName(student.getGradeName());
                charge.setStudentId(student.getStudentId());
                charge.setStudentName(student.getName());
                charge.setStudentSchool(student.getSchool());
                charge.setIsNewStudent(student.getRegClassAmount() > 0 ? 1 : 0);

                if (payWay.getPayWay() == 4) {//修正在线支付方式
                    charge.setPayWay(detectOnlinePayWay(payWay.getMorePayInfo()));
                } else {
                    charge.setPayWay(payWay.getPayWay());
                }

                charge.setPaidAmount(accountRecharge.getAmount());
                charge.setDiscountAmount(BigDecimal.ZERO);
                charge.setDiscountReason("");
                charge.setRemark(accountRecharge.getRemark());
                charge.setRefundAmount(BigDecimal.ZERO);
                charge.setCreateTime(accountRecharge.getCreateTime());
                charge.setUpdateTime(accountRecharge.getUpdateTime());

                try {
                    chargeService.insertSelective(charge);
                } catch (Exception e) {
                    chargeService.updateSelectiveById(charge);
                }
            }
        }
    }

    private String resolvePayChannelTransactionNo(int payWay, String payMoreInfo){
        if(StringUtils.isEmpty(payMoreInfo)){
            return null ;
        }

        JSONObject jsonObject = JSON.parseObject(payMoreInfo);
        if( payWay == 1  ){
            return jsonObject.getString("trxId");
        }else if(payWay == 4 ){
            return jsonObject.getString("transactionNo");
        }else {
            return null ;
        }
    }

    private Integer detectOnlinePayWay(String payMoreInfo) {
        if(payMoreInfo != null ){
            JSONObject jsonObject = JSON.parseObject(payMoreInfo);
            return jsonObject.getString("channel").contains("wx") ? 4 : jsonObject.getString("channel").contains("alipay") ? 5 : 6;
        }else {
            return 6 ;
        }
    }
}
